﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Media.Imaging;
using System.ComponentModel;
using System.Windows.Media;
using System.Windows;

namespace Pavilion.DesignerTool
{
    public class ColorGridModel: INotifyPropertyChanged
    {
        public int MaxHueAmount { get { return 250; } }
        public int MaxColorWidth { get { return 250; } }
        public int MaxColorHeight { get { return 249; } }

        private WriteableBitmap colorGridImage, hueGridImage;
        private SolidColorBrush selectedColor;
        private Point colorSelectorPosition;
        private float hueIncrement, hueAmount;

        public event PropertyChangedEventHandler PropertyChanged;
        public event Action<SolidColorBrush> SelectedColorChanged;

        public ColorGridModel()
        {
            this.hueIncrement = 360f / MaxHueAmount;
        }

        public void RenderColorGrid()
        {
            Microsoft.Xna.Framework.Vector2 position = new Microsoft.Xna.Framework.Vector2(0, 0);
            float total = 1f;
            float increment = 1f / MaxColorWidth;

            XnaImageRenderer render = new XnaImageRenderer();

            render.Begin(MaxColorWidth, MaxColorHeight);

            for (float s = increment; s <= total; s += increment)
            {
                for (float b = 0f; b <= total; b += increment)
                {
                    CColor color = new CColor();
                    DrawManager.Instance.DrawPointOnScreen(position, color.ConvertHsbToRgb(CurrentHueValue, s, b, 255));
                    position.X++;
                }

                position.Y++;
                position.X = 0f;
            }

            render.End();

            render.RenderTextureToBitmap();
            ColorGridImage = render.WriteableBitmap;

            UpdateCurrentColor();
        }

        public void RenderHueDisplay()
        {
            XnaImageRenderer render = new XnaImageRenderer();

            int yPos = 0;

            render.Begin(20, MaxHueAmount);

            for (float h = 0f; h <= 360f; h += hueIncrement)
            {
                CColor color = new CColor();
                DrawManager.Instance.DrawLineOnScreen(new Microsoft.Xna.Framework.Vector2(0, yPos), new Microsoft.Xna.Framework.Vector2(20, yPos), color.ConvertHsbToRgb(h, 1f, 0.5f, 255));
                yPos++;
            }

            render.End();

            render.RenderTextureToBitmap();
            HueGridImage = render.WriteableBitmap;
        }

        private void UpdateCurrentColor()
        {
            try
            {
                byte[] pixels = new byte[4];
                CroppedBitmap croppedBitmap = new CroppedBitmap(ColorGridImage, new Int32Rect((int)ColorSelectorPosition.X, (int)ColorSelectorPosition.Y, 1, 1));

                croppedBitmap.CopyPixels(pixels, 4, 0);

                SelectedColor = new SolidColorBrush(Color.FromArgb((byte)255, pixels[2], pixels[1], pixels[0]));
            }
            catch { }
        }

        private float CurrentHueValue
        {
            get { return HueAmount * hueIncrement; }
        }

        public Point ColorSelectorPosition
        {
            get { return colorSelectorPosition; }
            set
            {
                colorSelectorPosition = value;

                if (colorSelectorPosition.Y < 0)
                    colorSelectorPosition.Y = 0;
                else if (colorSelectorPosition.Y > MaxColorHeight)
                    colorSelectorPosition.Y = MaxColorHeight;

                if (colorSelectorPosition.X < 0)
                    colorSelectorPosition.X = 0;
                else if (colorSelectorPosition.X > MaxColorWidth)
                    colorSelectorPosition.X = MaxColorWidth;

                UpdateCurrentColor();
                OnPropertyChanged("ColorSelectorPosition"); }
        }

        public float HueAmount
        {
            get { return hueAmount; }
            set
            {
                hueAmount = value;

                if (hueAmount < 0)
                    hueAmount = 0;
                else if (hueAmount > MaxHueAmount)
                    hueAmount = MaxHueAmount;

                RenderColorGrid();
                OnPropertyChanged("HueAmount"); }
        }

        public SolidColorBrush SelectedColor
        {
            get { return selectedColor; }
            set { selectedColor = value; OnPropertyChanged("SelectedColor"); OnSelectedColorChanged(); }
        }

        public WriteableBitmap ColorGridImage
        {
            get { return colorGridImage; }
            set { colorGridImage = value; OnPropertyChanged("ColorGridImage"); }
        }

        public WriteableBitmap HueGridImage
        {
            get { return hueGridImage; }
            set { hueGridImage = value; OnPropertyChanged("HueGridImage"); }
        }

        private void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        private void OnSelectedColorChanged()
        {
            if (SelectedColorChanged != null)
                SelectedColorChanged(SelectedColor);
        }
    }
}
